package cz.su.pod.ksocializer.client.ui;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.Widget;

import cz.su.pod.ksocializer.client.activity.KSocializerCreateActivity;
import cz.su.pod.ksocializer.client.ui.widget.CharCounter;
import cz.su.pod.ksocializer.client.ui.widget.CreateButton;
import cz.su.pod.ksocializer.shared.domain.SocialNetwork;
import cz.su.pod.ksocializer.shared.domain.State;

public class KSocializerViewImpl extends Composite implements KSocializerView {

	private static SocializerViewImplUiBinder uiBinder = GWT
			.create(SocializerViewImplUiBinder.class);

	interface SocializerViewImplUiBinder extends
			UiBinder<Widget, KSocializerViewImpl> {
	}

	private final static int MAX_CHARACTERS = 140;
	private KSocializerCreateActivity activity;

	@UiField CharCounter charCounter;
	@UiField TextArea textArea;
	@UiField CreateButton createButton;
	@UiField FlowPanel statusPanel;
	
	public KSocializerViewImpl() {
		initWidget(uiBinder.createAndBindUi(this));
		init();
	}		

	@Override
	public void setKSocializerActivity(KSocializerCreateActivity activity) {
		this.activity = activity;
	}
	
	public KSocializerCreateActivity getActivity() {
		return activity;
	}

	@UiHandler("textArea")
	void onTextAreaKeyDown(KeyDownEvent event) {
		limitCharacters();
	}

	@UiHandler("textArea")
	void onTextAreaKeyUp(KeyUpEvent event) {
		limitCharacters();
	}		
	
	private void init() {
		registerCreateButtonHandler();
		charCounter.setMaxCharacters(MAX_CHARACTERS);
	}
	
	private void registerCreateButtonHandler() {
		createButton.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				postMessage();				
			}
		});
	}
	
	private String getMessage() {
		return textArea.getText();
	}

	private void limitCharacters() {
		int charCount = getCharactersCount();

		if (charCount >= MAX_CHARACTERS) {
			String text = textArea.getText();
			textArea.setText(text.substring(0, MAX_CHARACTERS));
			charCount = MAX_CHARACTERS;
		}
		
		charCounter.setCurrentCharacters(charCount);
	}

	private int getCharactersCount() {
		String text = textArea.getText();
		return text != null ? text.length() : 0;
	}
		
	private void postMessage() {
		getActivity().post(getMessage(), new AsyncCallback<Map<SocialNetwork,State>>() {
			
			@Override
			public void onSuccess(Map<SocialNetwork, State> result) {				
				String[] statuses = new String[result == null ? 0 : result.size()];		
								
				if (result != null) {
					int current = 0;
					for (Map.Entry<SocialNetwork, State> entry : result.entrySet()) {
						StringBuilder sb = new StringBuilder();
						sb.append(entry.getKey().toString()).append(" post status: ").append(entry.getValue().toString());
						statuses[current++] = sb.toString();
					}
				}
							
				showPostStatus(true, statuses);
			}
			
			@Override
			public void onFailure(Throwable caught) {
				showPostStatus(false, caught.getMessage());
			}
		});
	}
	
	private void showPostStatus(boolean successful, String... statuses) {
		statusPanel.clear();
		
		Label header = new Label("Status of posting message");
		statusPanel.add(header);
		
		for (String status : statuses) {
			Label statusLabel = new Label(status);
			statusPanel.add(statusLabel);
		}
		
		if (successful)
			statusPanel.setStyleName("status-ok", true);
		else
			statusPanel.setStyleName("status-error", true);
		
		statusPanel.setVisible(true);
	}
}
